//# sourceURL=http://uMapApp/Module/RoadLine/RoadLineModule
define([
    "mhjs/mhjs"
    , "uMap/uMap"
    , "uEarth/uEarth"
    , "../Module"
    , "../../UI/Panel/FloatPanel"
    , "../../UI/Panel/PanelBlock/ListBlock"
    , "../../UI/Panel/PanelBlock/PropertiesBlock"
    , "../../UI/Panel/Item/ListItem"
    , "../../UI/Layer"
    , "./RoadLine"
    , "../StakeNum/StakeNum"
    , "../StakeNum/Mileage"
], function (
    mhjs,
    uMap,
    uEarth,
    Module,
    FloatPanel,
    ListBlock,
    PropertiesBlock,
    ListItem,
    Layer,
    RoadLine,
    StakeNum,
    Mileage
) {

    function RoadLineModule(option) {

        var _this = this;
        Module.call(_this, option);

        _this.title = "道路边线";
        _this.icon = _this.app.icons.roadLine;
        _this.panels = [];
        _this.items = [];

        _this.listPanel = new FloatPanel({"class": "rightPanel", "showClose": true});
        _this.listPanel.listBlock = new ListBlock({"class": "fullBlock"});
        _this.listPanel.listBlock.title = "道路边线";
        _this.listPanel.append(_this.listPanel.listBlock);

        _this.listPanel.on("close", function () {
            _this.closePanel();
        });

        _this.panels.push(_this.listPanel);

        // _this.detailPanel = new FloatPanel({"class": "leftPanel", "showClose": true});
        // _this.detailPanel.propertiesBlock = new PropertiesBlock({"class": "fullBlock"});
        // _this.detailPanel.append(_this.detailPanel.propertiesBlock);
        //
        // _this.detailPanel.on("open", function () {
        //     _this.trigger("openDetail");
        // });
        //
        // _this.detailPanel.on("close", function () {
        //     _this.trigger("closeDetail");
        //     _this.unActiveAllItem();
        // });
        //
        // _this.panels.push(_this.detailPanel);

        _this.app.ui.layout.right.append(_this.listPanel);
        // _this.app.ui.layout.left.append(_this.detailPanel);
    }

    var _class = RoadLineModule;

    mhjs.Inherit(_class, Module);

    Object.defineProperties(_class.prototype, {
        "data"                               : {
            set: function (data) {
                var _this = this;
                _this.clear();
                _this._data = data;
                data && _this.renderList(data);
            },
            get: function () {
                return this._data;
            }
        },
        "renderList"                         : {
            value: function (list) {

                var _this = this;

                _this.roadlines = {
                    "numbers"   : {},
                    "directions": {}
                };

                $.each(list, function (i, item) {

                    if (_this.objMap) {
                        item = _this.objMap.format(item);
                    }

                    item.app = _this.app;
                    item.icon = _this.icon;

                    item.startStakeNum = StakeNum.transform(item["开始桩号"]);
                    item.stopStakeNum = StakeNum.transform(item["结束桩号"]);
                    item.positions = new uMap.Positions(item["位置"]);

                    var startPosition = _this.stakeNumModule.getCrossStakeNumPairPlanePoint(item.startStakeNum.no, item.positions.positions[0], item.positions.positions[1]);
                    var stopPosition = _this.stakeNumModule.getCrossStakeNumPairPlanePoint(item.stopStakeNum.no, item.positions.positions[item.positions.positions.length - 1], item.positions.positions[item.positions.positions.length - 2]);

                    if (startPosition) {
                        item.positions.positions[0] = startPosition;
                    }

                    if (stopPosition) {
                        item.positions.positions[item.positions.positions.length - 1] = stopPosition;
                    }


                    var roadLine = new RoadLine(item);

                    _this.roadlines.directions[roadLine["朝向"]] = _this.roadlines.directions[roadLine["朝向"]] || {};
                    _this.roadlines.directions[roadLine["朝向"]][roadLine.startStakeNum.no] = _this.roadlines.directions[roadLine["朝向"]][roadLine.startStakeNum.no] || {};
                    _this.roadlines.directions[roadLine["朝向"]][roadLine.startStakeNum.no][roadLine["车道线序号"]] = roadLine;

                    _this.roadlines.numbers[roadLine.startStakeNum.no] = _this.roadlines.numbers[roadLine.startStakeNum.no] || {};
                    _this.roadlines.numbers[roadLine.startStakeNum.no][roadLine["朝向"]] = _this.roadlines.numbers[roadLine.startStakeNum.no][roadLine["朝向"]] || {};
                    _this.roadlines.numbers[roadLine.startStakeNum.no][roadLine["朝向"]][roadLine["车道线序号"]] = roadLine;

                    _this.items.push(roadLine);

                    roadLine.listItem = new ListItem({
                        "title"   : roadLine.title,
                        "subtitle": roadLine["道路"] + " / " + roadLine["类型"],
                        "icon"    : _this.icon.base64,
                        "roadLine": roadLine
                    });

                    roadLine.listItem.on("click", function () {
                        _this.activeItem(roadLine);
                        roadLine.layer.active();
                        // _this.detailPanel.propertiesBlock.title = roadLine["开始桩号"];
                        // _this.detailPanel.propertiesBlock.map = _this.propertiesMap;
                        // _this.detailPanel.propertiesBlock.properties = roadLine;
                        // _this.detailPanel.open();

                    });

                    roadLine.listItem.on("hide", function (listItem) {
                        listItem.roadLine.close();
                    });

                    roadLine.listItem.on("show", function (listItem) {
                        listItem.roadLine.open();
                    });

                    _this.listPanel.listBlock.add(roadLine.listItem);

                });

                _this.listPanel.listBlock.filter = {
                    "param": "roadLine.searchKey"
                };

                _this.listPanel.listBlock.sorter = {
                    "param": {
                        "value": "roadLine.sortKey",
                        "label": "桩号/车道"
                    }
                };
            }
        },
        "clear"                              : {
            value: function () {
                var _this = this;

                $.each(_this.items, function (i, item) {
                    item.close();
                    item.listItem.remove();
                });

                _this._data = undefined;
                _this.items = [];
            }
        },
        "objMap"                             : {
            set: function (objMap) {
                var _this = this;
                _this._objMap = new mhjs.Map(objMap);
            },
            get: function () {
                return this._objMap;
            }
        },
        "propertiesMap"                      : {
            set: function (propertiesMap) {
                var _this = this;
                _this._propertiesMap = new mhjs.Map(propertiesMap);
            },
            get: function () {
                return this._propertiesMap;
            }
        },
        "open"                               : {
            value: function (forceReload) {
                var _this = this;

                _this.loadInit(function () {
                    _this.isOpened = true;
                    $.each(_this.items, function (i, item) {
                        item.open();
                    });
                    _this.trigger("open");
                    _this.trigger("toggle");
                }, forceReload);


            }
        },
        "loadInit"                           : {
            value: function (callback, forceReload) {

                var _this = this;

                if (forceReload || !_this.isLoaded) {

                    _this.load({}, function (data, mapData) {

                        _this.stakeNumModule.loadInit(function () {

                            if (mapData) {
                                _this.objMap = mapData.obj;
                                _this.propertiesMap = mapData.properties;
                            }

                            _this.data = data;
                            _this.isLoaded = true;

                            // console.log(_this.getSampledRoadCenterPositions("K61", "K88", 1000));

                            _this.trigger("loadInit");

                            callback && callback();
                        });
                    });

                } else {
                    callback && callback();
                }


            }
        },
        "openPanel"                          : {
            value: function () {
                var _this = this;
                if (!_this.isOpened) {
                    _this.open();
                }

                _this.listPanel.open();
                _this.isPanelOpened = true;
                _this.trigger("openPanel");

            }
        },
        "close"                              : {
            value: function () {
                var _this = this;
                _this.closePanel(false);
                _this.unActiveAllItem();
                $.each(_this.items, function (i, item) {
                    item.close();
                });
                _this.isOpened = false;
                _this.trigger("close");
                _this.trigger("toggle");
            }
        },
        "activeItem"                         : {
            value: function (item) {
                var _this = this;
                _this.unActiveAllItem();
                item.active();
                item.listItem.addClass("active");
                item.listItem.parent().animate({"scrollTop": item.listItem.dom[0].offsetTop});
            }
        },
        "unActiveAllItem"                    : {
            value: function () {
                var _this = this;
                $.each(_this.items, function (i, item) {
                    item.active(false);
                    item.listItem.removeClass("active");
                });
            }
        },
        "getRoadTrackCenterPositions"        : {
            value: function (leftRoadLine, rightRoadLine) {

                var _this = this;

                var stakeNums = [];
                var centerPositions = [];

                $.each(_this.roadlines.numbers, function (stakeNum, sameStakeNumRoadLines) {
                    stakeNums.push(stakeNum);
                });

                var firstStakeNum = stakeNums[0];
                var lastStakeNum = stakeNums[stakeNums.length - 1] + 1;

                $.each(stakeNums, function (i, stakeNum) {

                    var rightCenterLine = _this.roadlines.numbers[stakeNum][rightRoadLine.direction][rightRoadLine.roadLineNo];
                    var leftCenterLine = _this.roadlines.numbers[stakeNum][leftRoadLine.direction][leftRoadLine.roadLineNo];

                    $.each(rightCenterLine.positions.positions, function (j, position) {

                        //去除重复的尾点
                        if ((i === stakeNums.length - 1) || (j !== rightCenterLine.positions.positions.length - 1)) {

                            var currentPosition = position.cartesian;
                            var oppositePosition = leftCenterLine.positions.positions[j].cartesian;
                            var centerPosition = uEarth.Cartesian3.midpoint(currentPosition, oppositePosition, new uEarth.Cartesian3());

                            centerPositions.push(centerPosition);
                        }

                    });

                });

                return {
                    "startStakeNum": StakeNum.transform("K" + firstStakeNum),
                    "stopStakeNum" : StakeNum.transform("K" + lastStakeNum),
                    "positions"    : centerPositions
                };

            }
        },
        "getRoadCenterPositions"             : {
            value: function () {

                return this.getRoadTrackCenterPositions(
                    {
                        "direction" : "上行",
                        "roadLineNo": 3
                    }, {
                        "direction" : "下行",
                        "roadLineNo": 3
                    }
                );

            }
        },
        "getSampledRoadTrack"                : {
            value: function (leftRoadLine, rightRoadLine) {

                var _this = this;

                var centerPositions = _this.getRoadTrackCenterPositions(leftRoadLine, rightRoadLine);

                var sampledPosition = new uEarth.SampledPositionProperty();
                sampledPosition.setInterpolationOptions({
                    interpolationDegree   : 3,
                    interpolationAlgorithm: uEarth.HermitePolynomialApproximation
                });

                var sampledPositions = [];

                var startTime = uEarth.JulianDate.now().clone();
                var currentTime = startTime.clone();
                var speed = 1;
                var totalDistance = 0;

                $.each(centerPositions.positions, function (i, centerPosition) {

                    var distance = 0;

                    if (i > 0) {
                        distance = uEarth.Cartesian3.distance(centerPositions.positions[i - 1], centerPosition);
                    }

                    totalDistance += distance;

                    var periodTime = distance / speed;
                    uEarth.JulianDate.addSeconds(currentTime, periodTime, currentTime);

                    sampledPosition.addSample(currentTime.clone(), centerPosition);
                });

                sampledPosition.startStakeNum = centerPositions.startStakeNum;
                sampledPosition.stopStakeNum = centerPositions.stopStakeNum;
                sampledPosition.startTime = sampledPosition._property._times[0];
                sampledPosition.stopTime = sampledPosition._property._times[sampledPosition._property._times.length - 1];
                sampledPosition.totalDistance = totalDistance;

                return sampledPosition;

            }
        },
        "getSampledRoadCenter"               : {
            value: function () {

                return this.getSampledRoadTrack(
                    {
                        "direction" : "上行",
                        "roadLineNo": 3
                    }, {
                        "direction" : "下行",
                        "roadLineNo": 3
                    }
                );

            }
        },
        "getSampledRoadCenterPositions"      : {
            value: function (stakeNum, stopStakeNum, sampleDistance) {

                var _this = this;

                var sampledRoadCenter = _this.getSampledRoadCenter();
                sampleDistance = sampleDistance || 1;

                var result;

                if (stakeNum && stopStakeNum) {

                    result = [];

                    stakeNum = new Mileage(stakeNum);
                    stopStakeNum = new Mileage(stopStakeNum);

                    var startMeter = stakeNum.distance - sampledRoadCenter.startStakeNum.distance;
                    var stopMeter = stopStakeNum.distance - sampledRoadCenter.startStakeNum.distance;

                    for (var i = startMeter; i <= stopMeter / sampleDistance; ++i) {
                        var currentStakeNum = new Mileage(sampledRoadCenter.startStakeNum.distance + startMeter + i * sampleDistance);
                        result.push(_this.getSampledRoadCenterPositionHeading(currentStakeNum));
                    }

                } else if (stakeNum) {
                    result = _this.getSampledRoadCenterPositionHeading(stakeNum);
                }

                return result;

            }
        },
        "getSampledRoadTrackPositionHeading" : {
            value: function (leftRoadLine, rightRoadLine, stakeNum) {

                var _this = this;
                var sampledRoadCenter = _this.getSampledRoadTrack(leftRoadLine, rightRoadLine);
                var result;

                stakeNum = new Mileage(stakeNum);

                var currentTime = uEarth.JulianDate.addSeconds(
                    sampledRoadCenter.startTime,
                    stakeNum.distance - sampledRoadCenter.startStakeNum.distance,
                    new uEarth.JulianDate()
                );

                var currentPosition = sampledRoadCenter.getValue(currentTime);

                var previousPosition = sampledRoadCenter.getValue(uEarth.JulianDate.addSeconds(currentTime, -1, new uEarth.JulianDate()));
                var nextPosition = sampledRoadCenter.getValue(uEarth.JulianDate.addSeconds(currentTime, 1, new uEarth.JulianDate()));

                var heading = undefined;
                var direction = undefined;

                if (previousPosition || nextPosition) {

                    if (previousPosition) {
                        heading = uMap.Positions.getHeading(previousPosition, currentPosition);
                        direction = uMap.Positions.getDirection(previousPosition, currentPosition);
                    } else {
                        heading = uMap.Positions.getHeading(currentPosition, nextPosition);
                        direction = uMap.Positions.getDirection(currentPosition, nextPosition);
                    }

                    result = {
                        position : currentPosition,
                        heading  : heading,
                        direction: direction
                    };

                }

                return result;
            }
        },
        "getSampledRoadCenterPositionHeading": {
            value: function (stakeNum) {
                return this.getSampledRoadTrackPositionHeading(
                    {
                        "direction" : "上行",
                        "roadLineNo": 3
                    }, {
                        "direction" : "下行",
                        "roadLineNo": 3
                    },
                    stakeNum
                );
            }
        },
        "getRoadSection"                     : {
            value: function (option) {
                var _this = this;
                var polygonPositions = [];
                var rightLines = [];
                var leftLines = [];

                if (option.startStakeNum && option.stopStakeNum) {
                    var startStakeNum = StakeNum.transform(option.startStakeNum);
                    var stopStakeNum = StakeNum.transform(option.stopStakeNum);

                    var minStakeNumDistance = Math.min(startStakeNum.distance,stopStakeNum.distance);
                    var maxStakeNumDistance = Math.max(startStakeNum.distance,stopStakeNum.distance);

                    var start = Math.floor(minStakeNumDistance / 1000);
                    var stop = Math.ceil(maxStakeNumDistance / 1000);

                    var directionLeft = option.direction || "上行";
                    var directionRight = option.direction || "下行";
                    var leftRoadLineNum = !option.direction ? 0 : ((option.roadTrackNum === undefined) ? 0 : (option.roadTrackNum - 1));
                    var rightRoadLineNum = !option.direction ? 0 : ((option.roadTrackNum === undefined) ? 3 : option.roadTrackNum);


                    for (var i = start; i < stop; i++) {

                        if (_this.roadlines.directions[directionLeft][i]
                            && _this.roadlines.directions[directionLeft][i][leftRoadLineNum]
                            && _this.roadlines.directions[directionRight][stop - (i - start) - 1]
                            && _this.roadlines.directions[directionRight][stop - (i - start) - 1][rightRoadLineNum]
                        ) {
                            rightLines.push(_this.roadlines.directions[directionLeft][i][leftRoadLineNum]);
                            leftLines.push(_this.roadlines.directions[directionRight][stop - (i - start) - 1][rightRoadLineNum]);
                        }


                    }


                    $.each(rightLines, function (i, roadLine) {
                        $.each(roadLine.positions.positions, function (j, roadLinePosition) {
                            if (i === rightLines.length || j < roadLine.positions.length) {
                                polygonPositions.push(roadLinePosition);
                            }
                        });
                    });

                    $.each(leftLines, function (i, roadLine) {
                        $.each(roadLine.positions.positions, function (j, roadLinePosition) {
                            if (i === 0 || j !== 0) {
                                polygonPositions.push(roadLine.positions.positions[roadLine.positions.positions.length - j - 1]);
                            }
                        });
                    });


                }

                return polygonPositions;

            }
        }
    });

    return _class;

});